<template>
	<view>
		<view class="content" @touchstart="hideDrawer">
			<scroll-view class="msg-list" scroll-y="true" :scroll-with-animation="scrollAnimation" :scroll-top="scrollTop" :scroll-into-view="scrollToView" @scrolltoupper="loadHistory" upper-threshold="50">
				<!-- 加载历史数据waitingUI -->
				<view class="loading" v-if="is_showLoadin">
					<view class="spinner">
						<view class="rect1"></view>
						<view class="rect2"></view>
						<view class="rect3"></view>
						<view class="rect4"></view>
						<view class="rect5"></view>
					</view>
				</view>
				<view class="row" v-for="(row,index) in msgList" :key="index" :id="'msg'+row.chat_id">
					<!-- 自己发出的消息 -->
					<view class="my" v-if="row.from_id==memberID">
						
						<!-- 左-消息 -->
						<view class="left" >
							<view class="">
								<view class="username">
									<view class="time" style="color:#999999; text-align: right;"> {{row.create_time}} </view> 
								</view>
								<view class="" style="display: flex; align-items: center; justify-content: flex-end;">
									<!-- 文字消息 -->
									<view v-if="row.type=='text'" class="bubble">
										<rich-text :nodes="row.content"></rich-text>
									</view>
									<!-- 语言消息 -->
									<view v-if="row.type=='voice'" class="bubble voice" @tap="playVoice(row)" :class="playMsgid == row.chat_id?'play':''">
										<view class="length"></view>
										<view class="icon my-voice"></view>
									</view>
									<!-- 图片消息 -->
									<view v-if="row.type=='image'" class="bubble img" @tap="showPic(row)">
										<image :src="row.content"  mode="widthFix" > </image>
									</view>
									<!-- 红包 -->
									<view v-if="row.type=='redEnvelope'" class="bubble red-envelope" @tap="openRedEnvelope(row,index)">
										<image src="/static/img/red-envelope.png"></image>
										<view class="tis">
											<!-- 点击开红包 -->
										</view>
										<view class="blessing">
											{{row.content.blessing}}
										</view>
									</view>
									<!-- 商品 -->
									<view v-if="row.type=='goods_info'" class="bubble goods" >
										<view class="goods-image">
											<image class="" :src="row.content.image" mode=""></image>
										</view>
										<view class="goods-inner">
											<view class="goods-title">
												{{row.content.goods_name}}
											</view>
											<view class="goods-price">
												¥ {{row.content.sell_price}}
											</view>
										</view>
									</view>
								</view>
							</view>
						</view>
						<!-- 右-头像 -->
						<view class="right">
							<image src="/static/img/face.jpg"></image>
						</view>
					</view>
					<!-- 别人发出的消息 -->
					<view class="other" v-if="row.from_id!=memberID">
						<!-- 左-头像 -->
						<view class="left">
							<image src="/static/img/logo.png"></image>
						</view>
						<!-- 右-用户名称-时间-消息 -->
						<view class="right">
							<view class="username">
								<view class="name">爱八方客服</view> <view class="time">  {{row.create_time}}  </view>
							</view>
							<!-- 文字消息 -->
							<view v-if="row.type=='text'" class="bubble">
								<rich-text :nodes="row.content"></rich-text>
							</view>
							<!-- 语音消息 -->
							<view v-if="row.type=='voice'" class="bubble voice" @tap="playVoice(row)" :class="playMsgid == row.chat_id?'play':''">
								<view class="icon other-voice"></view>
								<view class="length">{{row.content.length}}</view>
							</view>
							<!-- 图片消息 -->
							<view v-if="row.type=='image'" class="bubble img" @tap="showPic(row)">
								<image :src="row.content" mode="aspectFill" ></image>
							</view>
							<!-- 红包 -->
							<view v-if="row.type=='redEnvelope'" class="bubble red-envelope" @tap="openRedEnvelope(row,index)">
								<image src="/static/img/red-envelope.png"></image>
								<view class="tis">
									<!-- 点击开红包 -->
								</view>
								<view class="blessing">
									{{row.content.blessing}}
								</view>
							</view>
						</view>
					</view>
				</view>
			</scroll-view>
		</view>
		<!-- 抽屉栏 -->
		<view class="popup-layer" :class="popupLayerClass" @touchmove.stop.prevent="discard">
			<!-- 表情 --> 
			<swiper class="emoji-swiper" :class="{hidden:hideEmoji}" indicator-dots="true" duration="150">
				<swiper-item v-for="(page,pid) in emojiList" :key="pid">
					<view v-for="(em,eid) in page" :key="eid" @tap="addEmoji(em)">
						<image mode="widthFix" :src="'/static/img/emoji/'+em.url"></image>
					</view>
				</swiper-item>
			</swiper>
			<!-- 更多功能 相册-拍照-红包 -->
			<view class="more-layer" :class="{hidden:hideMore}">
				<view class="list">
					<view class="box" @tap="chooseImage"><view class="icon tupian2"></view></view>
					<view class="box" @tap="camera"><view class="icon paizhao"></view></view>
					<view class="box" style="display: none;" @tap="handRedEnvelopes"><view class="icon hongbao"></view></view>
				</view>
			</view>
		</view>
		<!-- 底部输入栏 -->
		<view class="input-box" :class="popupLayerClass" @touchmove.stop.prevent="discard">
			<!-- H5下不能录音，输入栏布局改动一下 -->
			<!-- #ifndef H5 -->
			<view class="voice">
				<view class="icon" :class="isVoice?'jianpan':'yuyin'" @tap="switchVoice"></view>
			</view>
			<!-- #endif -->
			<!-- #ifdef H5 -->
			<view class="more" @tap="showMore">
				<view class="icon add"></view>
			</view>
			<!-- #endif -->
			<view class="textbox">
				<view class="voice-mode" :class="[isVoice?'':'hidden',recording?'recording':'']" @touchstart="voiceBegin" @touchmove.stop.prevent="voiceIng" @touchend="voiceEnd" @touchcancel="voiceCancel">{{voiceTis}}</view>
				<view class="text-mode"  :class="isVoice?'hidden':''">
					<view class="box">
						<textarea style="padding: 0 10upx;" auto-height="true" v-model="textMsg" @focus="textareaFocus"/>
					</view>
					<view class="em" style="display: none;" @tap="chooseEmoji">
						<view class="icon biaoqing"></view>
					</view>
				</view>
			</view>
			<!-- #ifndef H5 -->
			<view class="more" @tap="showMore">
				<view class="icon add"></view>
			</view>
			<!-- #endif -->
			<view class="send" :class="isVoice?'hidden':''" @tap="sendText">
				<view class="btn">发送</view>
			</view>
		</view>
		<!-- 录音UI效果 -->
		<view class="record" :class="recording?'':'hidden'">
			<view class="ing" :class="willStop?'hidden':''"><view class="icon luyin2" ></view></view>
			<view class="cancel" :class="willStop?'':'hidden'"><view class="icon chehui" ></view></view>
			<view class="tis" :class="willStop?'change':''">{{recordTis}}</view>
		</view>
		<!-- 红包弹窗 -->
		<view class="windows" :class="windowsState">
			<!-- 遮罩层 -->
			<view class="mask" @touchmove.stop.prevent="discard" @tap="closeRedEnvelope"></view>
			<view class="layer" @touchmove.stop.prevent="discard">
				<view class="open-redenvelope">
					<view class="top">
						<view class="close-btn">
							<view class="icon close" @tap="closeRedEnvelope"></view>
						</view>
						<image src="/static/img/im/face/face_1.jpg"></image>
					</view>
					<view class="from">来自{{redenvelopeData.from}}</view>
					<view class="blessing">{{redenvelopeData.blessing}}</view>
					<view class="money">{{redenvelopeData.money}}</view>
					<view class="showDetails" @tap="toDetails(redenvelopeData.rid)">
						查看领取详情 <view class="icon to"></view>
					</view>
				</view>
			</view>
			
		</view>
	</view>
</template>
<script>
	import {
	    mapState,
	    mapMutations
	} from 'vuex'
	export default {
		computed: {
		    ...mapState(['SystemInfo','token','memberID','socketData'])
		},
		data() {
			return {
				// 页数
				is_showLoadin:true,
				page: 1,
				//文字消息
				textMsg:'',
				//消息列表
				isHistoryLoading:false,
				scrollAnimation:false,
				scrollTop:0,
				scrollToView:'',
				msgList:[],
				msgImgList:[],
				myuid:0,
				
				//录音相关参数
				// #ifndef H5
				//H5不能录音
				RECORDER:uni.getRecorderManager(),
				// #endif
				isVoice:false,
				voiceTis:'按住 说话',
				recordTis:"手指上滑 取消发送",
				recording:false,
				willStop:false,
				initPoint:{identifier:0,Y:0},
				recordTimer:null,
				recordLength:0,
				
				//播放语音相关参数
				AUDIO:uni.createInnerAudioContext(),
				playMsgid:null,
				VoiceTimer:null,
				// 抽屉参数
				popupLayerClass:'',
				// more参数
				hideMore:true,
				//表情定义
				hideEmoji:true,
				emojiList:[],
				//表情图片图床名称 ，由于我上传的第三方图床名称会有改变，所以有此数据来做对应，您实际应用中应该不需要
				onlineEmoji:{},
				//红包相关参数
				windowsState:'',
				redenvelopeData:{
					rid:null,	//红包ID
					from:null,
					face:null,
					blessing:null,
					money:null
				}
			};
		},
		onLoad(option) {
			this.getMsgList();
			//语音自然播放结束
			this.AUDIO.onEnded((res)=>{
				this.playMsgid=null;
			});
			// #ifndef H5
			//录音开始事件
			this.RECORDER.onStart((e)=>{
				this.recordBegin(e);
			})
			//录音结束事件
			this.RECORDER.onStop((e)=>{
				this.recordEnd(e);
			})
			// #endif
			
			// 设置已经打开chat
			this.setChatView(true)
			
			// 监听消息事件
			uni.$on('chatMsg',(msginfo)=>{  
				console.log(JSON.stringify(msginfo))
				this.screenMsg(msginfo)
			})
					
			if(option.name){
				// 发送商品消息
				this.sendMsg('{"goods_name":"'+option.name+'","image":"'+option.image+'","sell_price":"'+option.sell_price+'"}','goods_info');
			}		
		},
		onUnload() {  
		// 移除监听事件  
			uni.$off('chatMsg');  
		},
		onBackPress(){
			// 设置已经关闭chat
			this.setChatView(false)
		},
		onShow(){
			this.scrollTop = 9999999;
			
		},
		methods:{
			...mapMutations(['getNetworkType','vuexRequest','vuexUploadFile','setChatMsgNum','setChatView']),
			// 接受消息(筛选处理)
			screenMsg(msg){
				// 用户消息
				switch (msg.type){
					case 'text':
						this.addTextMsg(msg);
						break;
					case 'voice':
						this.addVoiceMsg(msg);
						break;
					case 'image':
						this.addImgMsg(msg);
						break;
					case 'goods_info':
						this.addGoodstMsg(msg);
						break;
					case 'redEnvelope':
						this.addRedEnvelopeMsg(msg);
						break;
				}
				//非自己的消息震动 
				if(msg.from_id!=this.memberID){
					uni.vibrateLong();
				}
				
				this.$nextTick(function() {
					// 滚动到底
					this.scrollToView = 'msg'+msg.chat_id
				});
			},
			
			//触发滑动到顶部(加载历史信息记录)
			loadHistory(e){
				if(this.isHistoryLoading){
					return ;
				}
				this.isHistoryLoading = true;//参数作为进入请求标识，防止重复请求
				this.scrollAnimation = false;//关闭滑动动画
				let Viewid = this.msgList[0].chat_id;//记住第一个信息ID
				this.vuexRequest({
					url: '/api/addons/execute?route=chat/get-log&addon=orange-im&access-token=' + this.token,
					method: 'GET',
					data: {customer_id:1,'per-page': 100,chat_id:Viewid},
					success: (res)  => {
						// 消息列表
						let list = res.data.data.list
						// 获取消息中的图片,并处理显示尺寸
						for(let i=0;i<list.length;i++){
							if(list[i].type=="image"){
								list[i].content = this.setPicSize(list[i].content);
								this.msgImgList.unshift(list[i].content);
							}
							//list[i].chat_id = Math.floor(Math.random()*1000+1);
							this.msgList.unshift(list[i]);
						}
						
						//这段代码很重要，不然每次加载历史数据都会跳到顶部
						this.$nextTick(function() {
							this.scrollToView = 'msg'+Viewid;//跳转上次的第一行信息位置
							this.$nextTick(function() {
								this.scrollAnimation = true;//恢复滚动动画
							});
							
						});
						
						if(list.length != 0){
							this.isHistoryLoading = false;
						}else{
							this.is_showLoadin = false
						}
						this.page ++
					},
					fail: (err)  => {
						uni.showToast({
							icon: 'none',
							title: err.data.message,
							position:'bottom'
						})
					},
				})
			},
			// 加载初始页面消息
			getMsgList(){
				this.vuexRequest({
					url: '/api/addons/execute?route=chat/get-log&addon=orange-im&access-token=' + this.token,
					method: 'GET',
					data: {customer_id:1,'per-page': 100},
					success: (res)  => {
						let list = res.data.data.list.reverse();
						// 获取消息中的图片,并处理显示尺寸
						for(let i=0;i<list.length;i++){
							if(list[i].type=="image"){
								list[i].content = this.setPicSize(list[i].content);
								this.msgImgList.push(list[i].content);
							}
						}
						this.msgList = list;
						// 滚动到底部
						this.$nextTick(function() {
							//进入页面滚动到底部
							this.scrollTop = 9999;
							this.$nextTick(function() {
								this.scrollAnimation = true;
							});
						});
						this.page ++
						
						this.setChatMsgNum(0)
					},
					fail: (err)  => {
					},
				})
				
			},
			//处理图片尺寸，如果不处理宽高，新进入页面加载图片时候会闪
			setPicSize(content){
				// 让图片最长边等于设置的最大长度，短边等比例缩小，图片控件真实改变，区别于aspectFit方式。
				let maxW = uni.upx2px(350);//350是定义消息图片最大宽度
				let maxH = uni.upx2px(350);//350是定义消息图片最大高度
				if(content.w>maxW||content.h>maxH){
					let scale = content.w/content.h;
					content.w = scale>1?maxW:maxH*scale;
					content.h = scale>1?maxW/scale:maxH;
				}
				return content;
			},
			
			//更多功能(点击+弹出) 
			showMore(){
				this.isVoice = false;
				this.hideEmoji = true;
				if(this.hideMore){
					this.hideMore = false;
					this.openDrawer();
				}else{
					this.hideDrawer();
				}
			},
			// 打开抽屉
			openDrawer(){
				this.popupLayerClass = 'showLayer';
			},
			// 隐藏抽屉
			hideDrawer(){
				this.popupLayerClass = '';
				setTimeout(()=>{
					this.hideMore = true;
					this.hideEmoji = true;
				},150);
			},
			// 选择图片发送
			chooseImage(){
				this.getImage('album');
			},
			//拍照发送
			camera(){
				this.getImage('camera');
			},
			//发红包
			handRedEnvelopes(){
				uni.navigateTo({
					url:'HM-hand/HM-hand'
				});
				this.hideDrawer();
			},
			//选照片 or 拍照
			getImage(type){
				this.hideDrawer();
				uni.chooseImage({
					sourceType:[type],
					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图，默认二者都有
					success: (res)=>{
						for(let i=0;i<res.tempFilePaths.length;i++){
							uni.getImageInfo({
								src: res.tempFilePaths[i],
								success: (image)=>{
									//let msg = {url:res.tempFilePaths[i],w:image.width,h:image.height};
									this.sendMsg(res.tempFilePaths[i],'image');
								}
							});
						}
					}
				});
			},
			// 选择表情
			chooseEmoji(){
				this.hideMore = true;
				if(this.hideEmoji){
					this.hideEmoji = false;
					this.openDrawer();
				}else{
					this.hideDrawer();
				}
			},
			//添加表情
			addEmoji(em){
				this.textMsg+=em.alt;
			},
			
			//获取焦点，如果不是选表情ing,则关闭抽屉
			textareaFocus(){
				if(this.popupLayerClass=='showLayer' && this.hideMore == false){
					this.hideDrawer();
				}
			},
			// 发送文字消息
			sendText(){
				this.hideDrawer();//隐藏抽屉
				if(!this.textMsg){
					return;
				}
				let content = this.textMsg ///this.replaceEmoji(this.textMsg);
				//let msg = {text:content}
				this.sendMsg(content,'text');
				this.textMsg = '';//清空输入框
			},
			//替换表情符号为图片
			replaceEmoji(str){
				let replacedStr = str.replace(/\[([^(\]|\[)]*)\]/g,(item, index)=>{
					console.log("item: " + item);
					for(let i=0;i<this.emojiList.length;i++){
						let row = this.emojiList[i];
						for(let j=0;j<row.length;j++){
							let EM = row[j];
							if(EM.alt==item){
								//在线表情路径，图文混排必须使用网络路径，请上传一份表情到你的服务器后再替换此路径 
								//比如你上传服务器后，你的100.gif路径为https://www.xxx.com/emoji/100.gif 则替换onlinePath填写为https://www.xxx.com/emoji/
								let onlinePath = 'https://s2.ax1x.com/2019/04/12/'
								let imgstr = '<img src="'+onlinePath+this.onlineEmoji[EM.url]+'">';
								console.log("imgstr: " + imgstr);
								return imgstr;
							}
						}
					}
				});
				return '<div style="display: flex;align-items: center;word-wrap:break-word;">'+replacedStr+'</div>';
			},
			
			// 发送消息
			sendMsg(content,type){
				if(type == 'text'){	// 文本消息
					this.postMsg(content,type)
				}else if(type == 'goods_info'){	// 	商品消息
					this.postMsg(content,type)
				}else if(type == 'image'){	// 	图片消息
					uni.showLoading({
						title: '发送中'
					});		
					this.vuexUploadFile({
						url: '/api/v2/file/images?access-token=' + this.token,
						name: 'file',
						fileType: 'image',
						filePath: content,
						success: (res)  => {
							uni.hideLoading()
							this.postMsg(res.data.data.url,type)
						},
						fail: (err)  => {
							uni.hideLoading()
							uni.showToast({
								icon: 'none',
								title: err.data.message,
								position:'bottom'
							})
						},
					})
				}else if(type == 'voice'){		// 	音频消息
					uni.showLoading({
						title: '发送中'
					});		
					this.vuexUploadFile({
						url: '/api/v2/file/voices?access-token=' + this.token,
						name: 'file',
						fileType: 'audio',
						filePath: content,
						success: (res)  => {
							uni.hideLoading()
							this.postMsg(res.data.data.url,type)
						},
						fail: (err)  => {
							uni.hideLoading()
							uni.showToast({
								icon: 'none',
								title: err.data.message,
								position:'bottom'
							})
						},
					})
				}
			},
			postMsg(content,type){
				let data ={
					type: type,
					content: content,
					customer_id: this.socketData.customer_id
				}
				this.vuexRequest({
					url: '/api/addons/execute?route=chat/say&addon=orange-im&access-token=' + this.token,
					method: 'POST',
					data: data,
					success: (res)  => {
						//console.log(JSON.stringify(res))
					},
					fail: (err)  => {
						uni.showToast({
							icon: 'none',
							title: err.data.message,
							position:'bottom'
						})
					},
				})
			},
			// 添加商品消息到列表
			addGoodstMsg(msg){
				this.msgList.push(msg);
			},
			// 添加文字消息到列表
			addTextMsg(msg){
				this.msgList.push(msg);
			},
			// 添加语音消息到列表
			addVoiceMsg(msg){
				this.msgList.push(msg);
			},
			// 添加图片消息到列表
			addImgMsg(msg){
				msg.content = this.setPicSize(msg.content);
				this.msgImgList.push(msg.content);
				this.msgList.push(msg);
			},
			addRedEnvelopeMsg(msg){
				this.msgList.push(msg);
			},
			// 添加系统文字消息到列表
			addSystemTextMsg(msg){
				this.msgList.push(msg);
			},
			// 添加系统红包消息到列表
			addSystemRedEnvelopeMsg(msg){
				this.msgList.push(msg);
			},
			// 打开红包
			openRedEnvelope(msg,index){
				let rid = msg.content.rid;
			},
			// 关闭红包弹窗
			closeRedEnvelope(){
				this.windowsState = 'hide';
				setTimeout(()=>{
					this.windowsState = '';
				},200)
			},
			sendSystemMsg(content,type){
				let lastid = this.msgList[this.msgList.length-1].chat_id;
				lastid++;
				let row = {type:"system",msg:{id:lastid,type:type,content:content}};
				this.screenMsg(row)
			},
			//领取详情
			toDetails(rid){
				
			},
			// 预览图片
			showPic(msg){
				console.log(msg.content)
				uni.previewImage({
					indicator:"none",
					current:msg.content,
					urls: this.msgImgList
				});
			},
			// 播放语音
			playVoice(msg){
				this.playMsgid=msg.chat_id;
				this.AUDIO.src = msg.content;
				this.$nextTick(function() {
					this.AUDIO.play();
				});
			},
			// 录音开始
			voiceBegin(e){
				if(e.touches.length>1){
					return ;
				}
				this.initPoint.Y = e.touches[0].clientY;
				this.initPoint.identifier = e.touches[0].identifier;
				this.RECORDER.start({format:"mp3"});//录音开始,
			},
			//录音开始UI效果
			recordBegin(e){
				this.recording = true;
				this.voiceTis='松开 结束';
				this.recordLength = 0;
				this.recordTimer = setInterval(()=>{
					this.recordLength++;
				},1000)
			},
			// 录音被打断
			voiceCancel(){
				this.recording = false;
				this.voiceTis='按住 说话';
				this.recordTis = '手指上滑 取消发送'
				this.willStop = true;//不发送录音
				this.RECORDER.stop();//录音结束
			},
			// 录音中(判断是否触发上滑取消发送)
			voiceIng(e){
				if(!this.recording){
					return;
				}
				let touche = e.touches[0];
				//上滑一个导航栏的高度触发上滑取消发送
				if(this.initPoint.Y - touche.clientY>=uni.upx2px(100)){
					this.willStop = true;
					this.recordTis = '松开手指 取消发送'
				}else{
					this.willStop = false;
					this.recordTis = '手指上滑 取消发送'
				}
			},
			// 结束录音
			voiceEnd(e){
				if(!this.recording){
					return;
				}
				this.recording = false;
				this.voiceTis='按住 说话';
				this.recordTis = '手指上滑 取消发送'
				this.RECORDER.stop();//录音结束
			},
			//录音结束(回调文件)
			recordEnd(e){
				clearInterval(this.recordTimer);
				if(!this.willStop){
					console.log("e: " + JSON.stringify(e));
					let msg = {
						length:0,
						url:e.tempFilePath
					}
					let min = parseInt(this.recordLength/60);
					let sec = this.recordLength%60;
					min = min<10?'0'+min:min;
					sec = sec<10?'0'+sec:sec;
					msg.length = min+':'+sec;
					// 发送的音频不能低于一秒
					if(this.recordLength < 1){
						return !1
					}
					this.sendMsg(e.tempFilePath,'voice');
				}else{
					console.log('取消发送录音');
				}
				this.willStop = false;
			},
			// 切换语音/文字输入
			switchVoice(){
				this.hideDrawer();
				this.isVoice = this.isVoice?false:true;
			},
			discard(){
				return;
			}
		}
	}
</script>
<style lang="scss">
	@import "@/static/HM-chat/css/style.scss"; 
	.goods{
		display: flex;
		align-items: center;
		justify-content: flex-start;
		padding: 20rpx;
		width: 550rpx;
	}
	.goods-image {
		padding: 0 20rpx 0 0;
	}
	.goods-image image{
		width: 100rpx;
		height: 100rpx;
	}
	.goods-title{
		
	}
	.goods-price{
		white-space: nowrap;

	}
</style>